<?php
class Template{
	
	/**
	 * Cached kernel(Controller and Validator) scripts.
	 *
	 * @var string
	 */
	private static $javascripts = null;
	
	/**
	 * @var TemplateEngine
	 */
	private $engine;
	
	public function Template($tplDir = '',$tmpDir = '',$cache = 0){
		global $CMSPAD_CONSTANTS,$stylesheets,$javascripts;
		
		if(!$tplDir){
			$tplDir = CMSPAD_TEMPLATE_PATH;
			if(!file_exists($tplDir)){
				mkdir($tplDir,0777);
			}
		}
		
		if(!$tmpDir){
			$tmpDir = CMSPAD_TEMPORARY_ABSPATH;
			if(!file_exists($tmpDir)){
				mkdir($tmpDir,0777);
			}
			$tmpDir .= 'tpl';
			if(!file_exists($tmpDir)){
				mkdir($tmpDir,0777);
			}
		}

		cmspad_import('template.TemplateEngine');
		$this->engine = new TemplateEngine($tplDir,$tmpDir);
		$this->engine->cache = intval($cache);
		
		// Set cmspad const attributes.
		foreach($CMSPAD_CONSTANTS as $constK=>$constV){
			$this->engine->addVariable($constK,$constV);
		}
		
		// Initialize kernel scripts if it did not initialize.
		if(self::$javascripts == null){
			// Add controller scripts;
			cmspad_import('Controller');
			$controller = Controller::getInstance();
			self::$javascripts = $controller->getControllerScripts();
			
			// Add validator scripts
			cmspad_import('Validator');
			$validatorScripts = Validator::getValidatorScripts();
			if($validatorScripts){
				self::$javascripts .= $validatorScripts;
			}
		}
		
		if($javascripts){
			$this->engine->addVariable('javascripts',self::$javascripts . "\t<script type=\"text/javascript\">" . $javascripts . "</script>");
		}else{
			$this->engine->addVariable('javascripts',self::$javascripts);
		}
		
		// Add page custom stylesheet codes;
		if($stylesheets){
			$this->engine->addVariable('stylesheets',"\t<style type=\"text/css\">" . $stylesheets . "</style>");
		}else{
			$this->engine->addVariable('stylesheets','');
		}
		
		// Set system functions
		$this->engine->addTagFunction("portlet",array(&$this,"__function_portlet"));
		$this->engine->addTagFunction("hyperlink",array(&$this,"__function_hyperlink"));
	}

	public function addVariable($key,$value){
		$this->engine->addVariable($key,$value);
	}

	public function addFunction($key,$func){
		$this->engine->addTagFunction($key,$func);
	}

	public static function debug(){
		return TemplateEngine::debug();
	}

	public function reset(){
		$this->engine->clearVariables();
	}

	public function output($tpl){
		return $this->engine->fetch($tpl . '.tpl');
	}

	public function getTemplateDir(){
		return $this->engine->getTemplateDirectory();
	}

	public function getTemporaryDir(){
		return $this->engine->getTemporaryDirectory();
	}

	public function __function_hyperlink($params){
		$portlet = NULL;
		$method = NULL;
		$arguments = array();
		foreach($params as $k=>$v){
			switch($k){
				case 'portlet':
					$portlet = $v;
					break;
				case 'page':
					$method = $v;
					break;
				default:
					$arguments[] = $v;
					break;
			}
		}

		// Default is the using portlet.
		if(!$portlet && $this->engine->getVariable('CMSPAD_PORTLET_NAME')){
			$portlet = $this->engine->getVariable('CMSPAD_PORTLET_NAME');
		}
		if(!$portlet){
			$portlet = 'DefaultPortal';
		}
		
		return cmspad_hyperlink($portlet, $method, $arguments);
	}

	/**
	 * @access private
	 */
	public function __function_portlet($params){
		$class = NULL;
		$method = NULL;
		
		$arguments = array();
		foreach($params as $k=>$v){
			switch($k){
				case 'name':
					$class = $v;
					break;
				case 'view':
					$method = $v;
					break;
				default:
					$arguments[] = $v;
					break;
			}
		}

		if($class && $method){
			$filePath = CMSPAD_PORTLET_ABSPATH . $class . '.php';
			if(is_file($filePath)){
				
				// Include portlet file path.
				include_once ($filePath);
				
				// Create portlet object.
				$className = cmspad_get_class_name($class);
				if(!$className){
					return "<{portlet name='$class' view='$method'}>";
				}
				
				// Create portlet object.
				$portlet = new $className();
				
				// The method name of portlet class is form[Method].
				$method = 'view' . ucfirst($method);
				if(method_exists($portlet,$method)){
					if($arguments){
						$return = call_user_func_array(array(&$portlet,$method),$arguments);
					}else{
						$return = call_user_func(array(&$portlet,$method));
					}
				}
				
				// Release portlet object.
				unset($portlet);
			}
			return isset($return)?$return:false;
		}else{
			return false;
		}
	}
}
?>